#!/usr/bin/env python3
"""
简化版后台图片上传服务器
使用纯Python标准库，无需额外依赖
"""

import os
import json
import uuid
import logging
from datetime import datetime
from http.server import HTTPServer, SimpleHTTPRequestHandler
import urllib.parse
import cgi
import shutil

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 配置
UPLOAD_FOLDER = 'static/uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico'}
MAX_FILE_SIZE = 10 * 1024 * 1024  # 10MB

# 确保上传目录存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

def allowed_file(filename):
    """检查文件类型是否允许"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def format_file_size(size):
    """格式化文件大小"""
    for unit in ['B', 'KB', 'MB', 'GB']:
        if size < 1024:
            return f"{size:.1f} {unit}"
        size /= 1024
    return f"{size:.1f} TB"

class ImageUploadHandler(SimpleHTTPRequestHandler):
    """自定义HTTP请求处理器"""
    
    def do_GET(self):
        """处理GET请求"""
        logger.info(f"GET请求: {self.path}")
        
        # API接口 - 获取图片列表
        if self.path == '/api/images':
            self.handle_get_images()
            return
        
        # API接口 - 获取统计信息
        if self.path == '/api/stats':
            self.handle_get_stats()
            return
        
        # 静态文件服务
        if self.path.startswith('/static/uploads/'):
            self.serve_uploaded_file()
            return
        
        # 后台管理页面
        if self.path == '/admin':
            self.serve_admin_page()
            return
        
        # 默认返回404
        self.send_error(404, "页面未找到")
    
    def do_POST(self):
        """处理POST请求"""
        logger.info(f"POST请求: {self.path}")
        
        # 图片上传接口
        if self.path == '/api/upload':
            self.handle_upload()
            return
        
        # 默认返回404
        self.send_error(404, "接口未找到")
    
    def do_DELETE(self):
        """处理DELETE请求"""
        logger.info(f"DELETE请求: {self.path}")
        
        # 删除图片接口
        if self.path.startswith('/api/delete/'):
            self.handle_delete()
            return
        
        # 默认返回404
        self.send_error(404, "接口未找到")
    
    def handle_get_images(self):
        """获取图片列表"""
        try:
            images = []
            
            # 遍历上传目录
            for filename in os.listdir(UPLOAD_FOLDER):
                if filename.endswith('.json'):
                    json_path = os.path.join(UPLOAD_FOLDER, filename)
                    try:
                        with open(json_path, 'r', encoding='utf-8') as f:
                            image_info = json.load(f)
                            images.append(image_info)
                    except Exception as e:
                        logger.warning(f"读取图片信息失败: {json_path}, {e}")
            
            # 按上传时间排序（最新的在前）
            images.sort(key=lambda x: x.get('upload_time', ''), reverse=True)
            
            response = {
                'success': True,
                'data': images,
                'total': len(images)
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            logger.error(f"获取图片列表失败: {e}")
            self.send_error(500, "获取图片列表失败")
    
    def handle_get_stats(self):
        """获取统计信息"""
        try:
            total_images = 0
            total_size = 0
            last_upload = None
            
            # 遍历上传目录
            for filename in os.listdir(UPLOAD_FOLDER):
                if filename.endswith('.json'):
                    json_path = os.path.join(UPLOAD_FOLDER, filename)
                    try:
                        with open(json_path, 'r', encoding='utf-8') as f:
                            image_info = json.load(f)
                            total_images += 1
                            total_size += image_info.get('size', 0)
                            upload_time = image_info.get('upload_time')
                            if upload_time and (not last_upload or upload_time > last_upload):
                                last_upload = upload_time
                    except Exception as e:
                        logger.warning(f"读取图片信息失败: {json_path}, {e}")
            
            response = {
                'success': True,
                'data': {
                    'total_images': total_images,
                    'total_size': total_size,
                    'total_size_formatted': format_file_size(total_size),
                    'last_upload': last_upload
                }
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            logger.error(f"获取统计信息失败: {e}")
            self.send_error(500, "获取统计信息失败")
    
    def handle_upload(self):
        """处理图片上传"""
        try:
            # 解析multipart表单数据
            content_type = self.headers.get('Content-Type', '')
            if not content_type.startswith('multipart/form-data'):
                self.send_error(400, "不支持的Content-Type")
                return
            
            # 读取请求体
            content_length = int(self.headers.get('Content-Length', 0))
            if content_length > MAX_FILE_SIZE:
                self.send_error(400, "文件过大")
                return
            
            post_data = self.rfile.read(content_length)
            
            # 简单的multipart解析
            boundary = content_type.split('boundary=')[1].encode()
            parts = post_data.split(boundary)
            
            file_data = None
            filename = None
            
            for part in parts:
                if b'Content-Disposition: form-data' in part and b'filename=' in part:
                    # 提取文件名
                    filename_match = part.split(b'filename="')[1].split(b'"')[0]
                    filename = filename_match.decode('utf-8')
                    
                    # 提取文件数据
                    header_end = part.find(b'\r\n\r\n')
                    if header_end != -1:
                        file_data = part[header_end + 4:].rstrip(b'\r\n')
                        break
            
            if not file_data or not filename:
                self.send_error(400, "未找到上传文件")
                return
            
            if not allowed_file(filename):
                self.send_error(400, "不支持的文件类型")
                return
            
            # 生成唯一文件名
            file_extension = filename.rsplit('.', 1)[1].lower()
            unique_filename = f"{uuid.uuid4().hex}.{file_extension}"
            
            # 保存文件
            file_path = os.path.join(UPLOAD_FOLDER, unique_filename)
            with open(file_path, 'wb') as f:
                f.write(file_data)
            
            # 生成文件信息
            file_info = {
                'original_name': filename,
                'filename': unique_filename,
                'size': len(file_data),
                'upload_time': datetime.now().isoformat(),
                'url': f'/static/uploads/{unique_filename}'
            }
            
            # 保存文件信息到JSON
            info_path = os.path.join(UPLOAD_FOLDER, f"{unique_filename}.json")
            with open(info_path, 'w', encoding='utf-8') as f:
                json.dump(file_info, f, ensure_ascii=False, indent=2)
            
            logger.info(f"图片上传成功: {unique_filename}")
            
            response = {
                'success': True,
                'message': '上传成功',
                'data': file_info
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            logger.error(f"上传处理失败: {e}")
            self.send_error(500, "上传失败")
    
    def handle_delete(self):
        """删除图片"""
        try:
            # 从URL中提取文件名
            filename = self.path.split('/')[-1]
            
            if not allowed_file(filename):
                self.send_error(400, "无效的文件名")
                return
            
            # 删除图片文件
            image_path = os.path.join(UPLOAD_FOLDER, filename)
            if os.path.exists(image_path):
                os.remove(image_path)
            
            # 删除信息文件
            info_path = os.path.join(UPLOAD_FOLDER, f"{filename}.json")
            if os.path.exists(info_path):
                os.remove(info_path)
            
            logger.info(f"图片删除成功: {filename}")
            
            response = {
                'success': True,
                'message': '删除成功'
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            logger.error(f"删除图片失败: {e}")
            self.send_error(500, "删除失败")
    
    def serve_uploaded_file(self):
        """提供上传的图片文件"""
        try:
            filename = self.path.split('/')[-1]
            
            if not allowed_file(filename):
                self.send_error(400, "无效的文件名")
                return
            
            file_path = os.path.join(UPLOAD_FOLDER, filename)
            if not os.path.exists(file_path):
                self.send_error(404, "文件不存在")
                return
            
            # 设置正确的Content-Type
            extension = filename.rsplit('.', 1)[1].lower()
            content_type = {
                'jpg': 'image/jpeg',
                'jpeg': 'image/jpeg',
                'png': 'image/png',
                'gif': 'image/gif',
                'webp': 'image/webp',
                'bmp': 'image/bmp',
                'ico': 'image/x-icon'
            }.get(extension, 'application/octet-stream')
            
            with open(file_path, 'rb') as f:
                file_data = f.read()
            
            self.send_response(200)
            self.send_header('Content-Type', content_type)
            self.send_header('Content-Length', str(len(file_data)))
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(file_data)
            
        except Exception as e:
            logger.error(f"文件访问失败: {e}")
            self.send_error(500, "文件访问失败")
    
    def serve_admin_page(self):
        """提供后台管理页面"""
        try:
            # 读取后台管理页面文件
            admin_file = 'backend_admin.html'
            if os.path.exists(admin_file):
                with open(admin_file, 'r', encoding='utf-8') as f:
                    html_content = f.read()
                
                self.send_response(200)
                self.send_header('Content-Type', 'text/html; charset=utf-8')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(html_content.encode('utf-8'))
            else:
                self.send_error(404, "管理页面不存在")
                
        except Exception as e:
            logger.error(f"管理页面访问失败: {e}")
            self.send_error(500, "管理页面访问失败")
    
    def send_json_response(self, data):
        """发送JSON响应"""
        json_data = json.dumps(data, ensure_ascii=False, indent=2)
        self.send_response(200)
        self.send_header('Content-Type', 'application/json; charset=utf-8')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.end_headers()
        self.wfile.write(json_data.encode('utf-8'))
    
    def do_OPTIONS(self):
        """处理OPTIONS请求（CORS预检）"""
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.end_headers()

def run_server(port=5000):
    """运行服务器"""
    server_address = ('', port)
    httpd = HTTPServer(server_address, ImageUploadHandler)
    
    logger.info(f"🚀 后台图片上传服务器启动成功！")
    logger.info(f"📋 管理页面: http://localhost:{port}/admin")
    logger.info(f"📁 上传目录: {UPLOAD_FOLDER}")
    logger.info(f"🔧 API 端点: http://localhost:{port}/api")
    logger.info("=" * 50)
    logger.info("API 接口说明:")
    logger.info("GET  /api/images          - 获取图片列表")
    logger.info("GET  /api/stats           - 获取统计信息")
    logger.info("POST /api/upload          - 上传图片")
    logger.info("DELETE /api/delete/<文件名> - 删除图片")
    logger.info("GET  /static/uploads/<文件名> - 访问图片")
    logger.info("=" * 50)
    
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        logger.info("\n👋 服务器正在关闭...")
        httpd.shutdown()
        logger.info("✅ 服务器已关闭")

if __name__ == '__main__':
    run_server()